package utils

import (
	"errors"
	"github.com/golang-jwt/jwt/v5"
	"golang.org/x/crypto/bcrypt"
	"time"
)

// HashPassword 密码加密函数
// @Summary 密码加密
// @Description 使用bcrypt算法对明文密码进行哈希加密
// @Tags 工具函数
// @Accept string
// @Produce string
// @Param password string true "明文密码"
// @Success 200 {string} string "哈希后的密码"
// @Failure 500 {error} error "加密失败"
func HashPassword(pwd string) (string, error) {
	// 使用 bcrypt 算法生成密码哈希，成本因子为12
	hash, err := bcrypt.GenerateFromPassword([]byte(pwd), 12)
	return string(hash), err
}

// GenerateJWT JWT令牌生成函数
// @Summary 生成JWT令牌
// @Description 根据用户名生成JWT身份认证令牌
// @Tags 工具函数
// @Accept string
// @Produce string
// @Param username string true "用户名"
// @Success 200 {string} string "JWT令牌"
// @Failure 500 {error} error "令牌生成失败"
func GenerateJWT(username string) (string, error) {
	// 创建令牌，设置加密算法和有效载荷
	token := jwt.NewWithClaims(jwt.SigningMethodHS256, jwt.MapClaims{
		"username": username,                              // 用户名
		"exp":      time.Now().Add(time.Hour * 72).Unix(), // 72小时后过期
	})

	// 使用密钥签名并返回令牌
	signedToken, err := token.SignedString([]byte("your_secret_key"))
	return "Bearer " + signedToken, err
}

// CheckPassword 密码验证函数
// @Summary 验证密码
// @Description 比较明文密码与存储的哈希值是否匹配
// @Tags 工具函数
// @Accept string,string
// @Produce bool
// @Param password string true "明文密码"
// @Param hash string true "密码哈希值"
// @Success 200 {bool} bool "是否匹配"
func CheckPassword(password string, hash string) bool {
	// 比较密码与哈希值
	err := bcrypt.CompareHashAndPassword([]byte(hash), []byte(password))
	return err == nil
}

// ParseJWT JWT令牌解析函数
// @Summary 解析JWT令牌
// @Description 验证并解析JWT令牌，提取用户名信息
// @Tags 工具函数
// @Accept string
// @Produce string
// @Param tokenString string true "JWT令牌"
// @Success 200 {string} string "用户名"
// @Failure 500 {error} error "令牌解析失败"
func ParseJWT(tokenString string) (string, error) {
	// 处理Bearer token格式
	if len(tokenString) > 7 && tokenString[:7] == "Bearer " {
		tokenString = tokenString[7:]
	}

	// 解析JWT token
	token, err := jwt.Parse(tokenString, func(token *jwt.Token) (interface{}, error) {
		// 验证签名算法是否为HMAC
		if _, ok := token.Method.(*jwt.SigningMethodHMAC); !ok {
			return nil, errors.New("unexpected signing method")
		}

		// 返回HMAC签名密钥（实际应用中应从配置获取）
		return []byte("your_secret_key"), nil
	})

	// 错误处理
	if err != nil {
		return "", err
	}

	// 验证token是否有效并提取claims
	if claims, ok := token.Claims.(jwt.MapClaims); ok && token.Valid {
		// 从claims中提取username字段
		username, ok := claims["username"].(string)
		if !ok {
			return "", errors.New("username claim is invalid or missing")
		}
		return username, nil
	}

	// 令牌无效
	return "", err
}
